"""
清空景点数据并重新从高德地图API获取有图片的景点数据
"""
import time
from django.core.management.base import BaseCommand
from django.conf import settings
from apps.attractions.models import Attraction
from utils.amap_client import AMapClient
from decimal import Decimal


class Command(BaseCommand):
    help = '清空景点数据并重新从高德地图API获取有图片的景点数据'

    # 各类别的搜索关键词和类型
    CATEGORY_CONFIG = {
        'cultural': {
            'name': '文化古迹',
            'keywords': ['博物馆', '纪念馆', '古迹', '遗址', '古建筑', '文化馆', '历史建筑', '文物', '古塔', '古寺'],
            'types': '风景名胜|博物馆|纪念馆|古迹|文物古迹',
        },
        'natural': {
            'name': '自然风光',
            'keywords': ['公园', '风景区', '湖泊', '山', '自然', '生态', '湿地', '森林公园', '植物园', '动物园'],
            'types': '风景名胜|公园广场|自然景观|生态公园',
        },
        'modern': {
            'name': '现代建筑',
            'keywords': ['科技馆', '展览馆', '地标', '现代建筑', '广场', '商业中心', '摩天轮', '观景台', '塔', '桥'],
            'types': '风景名胜|科技馆|展览馆|广场|地标建筑',
        },
        'food': {
            'name': '美食购物',
            'keywords': ['美食街', '小吃街', '购物街', '商业街', '美食广场', '夜市', '步行街', '商业中心'],
            'types': '餐饮服务|购物服务|美食|商业街',
        }
    }

    def add_arguments(self, parser):
        parser.add_argument(
            '--location',
            type=str,
            default='115.89,28.68',
            help='中心点坐标（经度,纬度），默认南昌市中心'
        )
        parser.add_argument(
            '--radius',
            type=int,
            default=50000,
            help='搜索半径（米），默认50000（50公里）'
        )
        parser.add_argument(
            '--min-per-category',
            type=int,
            default=10,
            help='每个类别最少数量，默认10'
        )
        parser.add_argument(
            '--max-per-category',
            type=int,
            default=30,
            help='每个类别最大数量，默认30'
        )
        parser.add_argument(
            '--skip-clear',
            action='store_true',
            help='跳过清空步骤（不清空现有数据）'
        )

    def handle(self, *args, **options):
        api_key = settings.AMAP_CONFIG.get('API_KEY')
        if not api_key or api_key == 'your_amap_api_key':
            self.stdout.write(self.style.ERROR('❌ 高德地图API Key未配置！'))
            return

        amap_client = AMapClient(api_key)
        location = options['location']
        radius = options['radius']
        min_per_category = options['min_per_category']
        max_per_category = options['max_per_category']
        skip_clear = options['skip_clear']

        self.stdout.write(self.style.SUCCESS('=' * 60))
        self.stdout.write(self.style.SUCCESS('清空并重新获取景点数据'))
        self.stdout.write(self.style.SUCCESS('=' * 60))
        self.stdout.write(f'位置: {location}')
        self.stdout.write(f'半径: {radius}米')
        self.stdout.write(f'每类最少: {min_per_category}个')
        self.stdout.write(f'每类最多: {max_per_category}个')
        self.stdout.write('')

        # 步骤1：清空现有数据
        if not skip_clear:
            self.stdout.write(self.style.WARNING('步骤1: 清空现有景点数据...'))
            total_deleted = Attraction.objects.all().delete()[0]
            self.stdout.write(self.style.SUCCESS(f'✓ 已删除 {total_deleted} 个景点'))
            self.stdout.write('')

        # 步骤2：获取各类别景点数据
        self.stdout.write(self.style.SUCCESS('步骤2: 获取各类别景点数据（仅获取有图片的）...'))
        self.stdout.write('')

        total_created = 0
        total_images = 0
        category_stats = {}

        for cat_key, config in self.CATEGORY_CONFIG.items():
            self.stdout.write(f"处理类别: {config['name']} ({cat_key})")
            self.stdout.write('-' * 60)

            created_count = 0
            images_count = 0
            all_pois = []
            seen_poi_ids = set()

            # 使用多个关键词搜索
            for keyword in config['keywords']:
                if len(all_pois) >= max_per_category:
                    break

                self.stdout.write(f'  搜索关键词: {keyword}')
                page = 1

                while len(all_pois) < max_per_category:
                    try:
                        result = amap_client.search_pois_by_location(
                            location=location,
                            keywords=keyword,
                            types=config['types'],
                            radius=radius,
                            page=page,
                            page_size=20
                        )

                        if result.get('status') != '1':
                            break

                        pois = result.get('pois', [])
                        if not pois:
                            break

                        # 去重
                        for poi in pois:
                            poi_id = poi.get('id', '')
                            if poi_id and poi_id not in seen_poi_ids:
                                seen_poi_ids.add(poi_id)
                                all_pois.append(poi)

                        if len(pois) < 20:
                            break

                        page += 1
                        time.sleep(0.3)

                    except Exception as e:
                        self.stdout.write(f'    ⚠ 搜索失败: {str(e)}')
                        break

            # 限制数量
            all_pois = all_pois[:max_per_category]
            self.stdout.write(f'  找到 {len(all_pois)} 个POI，开始处理...\n')

            # 处理每个POI，只保存有图片的
            for idx, poi in enumerate(all_pois, 1):
                try:
                    poi_id = poi.get('id', '')
                    poi_name = poi.get('name', '')
                    location_str = poi.get('location', '')

                    if not poi_id or not location_str:
                        continue

                    loc_parts = location_str.split(',')
                    if len(loc_parts) < 2:
                        continue

                    longitude = Decimal(loc_parts[0])
                    latitude = Decimal(loc_parts[1])
                    address = poi.get('address', '') or ''

                    # 获取POI详情和图片
                    image_urls = []
                    description = poi.get('intro', '') or ''
                    rating = 4.0
                    ticket_price = Decimal('0.00')
                    open_time = None
                    close_time = None

                    try:
                        time.sleep(0.3)
                        poi_detail = amap_client.get_poi_detail(poi_id)

                        if poi_detail.get('status') == '1' and poi_detail.get('pois'):
                            poi_data = poi_detail['pois'][0]

                            # 提取图片（关键步骤）
                            photos = poi_data.get('photos', [])
                            if not photos:
                                photos = poi_data.get('photo', [])

                            # 处理不同格式的图片数据
                            if isinstance(photos, str):
                                import json
                                try:
                                    photos = json.loads(photos)
                                except:
                                    photos = []

                            if isinstance(photos, list):
                                for photo in photos[:10]:  # 最多10张
                                    url = None
                                    if isinstance(photo, dict):
                                        url = photo.get('url') or photo.get('src') or photo.get('title')
                                    elif isinstance(photo, str):
                                        url = photo

                                    if url and isinstance(url, str):
                                        # 确保URL完整
                                        if not url.startswith('http'):
                                            if url.startswith('//'):
                                                url = 'https:' + url
                                            elif url.startswith('/'):
                                                url = 'https://restapi.amap.com' + url
                                            else:
                                                continue
                                        image_urls.append(url)

                            # 提取描述
                            if poi_data.get('intro'):
                                description = poi_data.get('intro')
                            elif poi_data.get('content'):
                                description = poi_data.get('content')

                            # 提取评分
                            rating_str = poi_data.get('rating', '')
                            if rating_str:
                                try:
                                    rating = float(rating_str)
                                except:
                                    pass

                            # 提取价格
                            cost = poi_data.get('cost', '')
                            if cost:
                                import re
                                match = re.search(r'(\d+\.?\d*)', str(cost))
                                if match:
                                    try:
                                        ticket_price = Decimal(match.group(1))
                                    except:
                                        pass

                            # 解析营业时间
                            opentime = poi_data.get('opentime', '')
                            if opentime and ';' in opentime:
                                time_ranges = opentime.split(';')
                                if time_ranges:
                                    first_range = time_ranges[0]
                                    if '-' in first_range:
                                        times = first_range.split('-')
                                        if len(times) == 2:
                                            try:
                                                from datetime import datetime
                                                open_time = datetime.strptime(times[0].strip(), '%H:%M').time()
                                                close_time = datetime.strptime(times[1].strip(), '%H:%M').time()
                                            except:
                                                pass

                    except Exception as e:
                        self.stdout.write(f'    ⚠ 获取详情失败: {str(e)}')

                    # 数据清洗：只保存有图片的景点
                    if not image_urls:
                        self.stdout.write(f'  [{idx}/{len(all_pois)}] {poi_name} - ⏭ 跳过（无图片）')
                        continue

                    # 数据清洗：清理描述
                    if description:
                        description = description.strip()
                        if len(description) > 500:
                            description = description[:500] + '...'

                    # 数据清洗：确保名称不为空
                    if not poi_name or not poi_name.strip():
                        continue

                    # 计算热度
                    popularity = int(rating * 20)
                    if popularity < 20:
                        popularity = 20  # 最低热度

                    # 创建景点（只保存有图片的）
                    try:
                        attraction = Attraction.objects.create(
                            name=poi_name.strip(),
                            latitude=latitude,
                            longitude=longitude,
                            address=address.strip() if address else '',
                            description=description,
                            category=cat_key,
                            ticket_price=ticket_price,
                            open_time=open_time,
                            close_time=close_time,
                            popularity=popularity,
                            rating=rating,
                            amap_poi_id=poi_id,
                            amap_image_urls=image_urls[:10],  # 最多保存10张
                        )

                        created_count += 1
                        images_count += len(image_urls)
                        total_created += 1
                        total_images += len(image_urls)

                        self.stdout.write(
                            self.style.SUCCESS(
                                f'  [{idx}/{len(all_pois)}] ✓ {poi_name} - {len(image_urls)}张图片'
                            )
                        )

                    except Exception as e:
                        self.stdout.write(
                            self.style.ERROR(f'  [{idx}/{len(all_pois)}] ✗ {poi_name} - 创建失败: {str(e)}')
                        )

                except Exception as e:
                    self.stdout.write(
                        self.style.ERROR(f'  [{idx}/{len(all_pois)}] ✗ 处理失败: {str(e)}')
                    )

            category_stats[cat_key] = {
                'created': created_count,
                'images': images_count
            }

            self.stdout.write('')
            self.stdout.write(f'{config["name"]} 完成: 创建{created_count}个，图片{images_count}张')
            self.stdout.write('')

        # 输出总结
        self.stdout.write('')
        self.stdout.write(self.style.SUCCESS('=' * 60))
        self.stdout.write(self.style.SUCCESS('数据获取完成！'))
        self.stdout.write(self.style.SUCCESS('=' * 60))
        self.stdout.write(f'总计创建: {total_created} 个景点')
        self.stdout.write(f'总计图片: {total_images} 张')
        self.stdout.write('')
        self.stdout.write('各类别统计:')
        for cat_key, stats in category_stats.items():
            config = self.CATEGORY_CONFIG[cat_key]
            self.stdout.write(
                f'  {config["name"]}: {stats["created"]}个景点, {stats["images"]}张图片'
            )

        # 数据清洗：检查并修复数据
        self.stdout.write('')
        self.stdout.write(self.style.SUCCESS('步骤3: 数据清洗和整理...'))
        
        # 清理空数据
        empty_desc = Attraction.objects.filter(description__isnull=True) | Attraction.objects.filter(description='')
        empty_desc.update(description='暂无描述')
        
        # 确保所有景点都有POI ID
        no_poi = Attraction.objects.filter(amap_poi_id__isnull=True) | Attraction.objects.filter(amap_poi_id='')
        no_poi_count = no_poi.count()
        if no_poi_count > 0:
            self.stdout.write(f'  发现 {no_poi_count} 个没有POI ID的景点（已跳过）')
        
        # 确保所有景点都有图片
        no_images = Attraction.objects.filter(amap_image_urls__isnull=True) | Attraction.objects.filter(amap_image_urls=[])
        no_images_count = no_images.count()
        if no_images_count > 0:
            self.stdout.write(f'  发现 {no_images_count} 个没有图片的景点（已跳过）')
            no_images.delete()
        
        self.stdout.write(self.style.SUCCESS('✓ 数据清洗完成'))
        self.stdout.write('')
        self.stdout.write(self.style.SUCCESS('=' * 60))
        self.stdout.write(self.style.SUCCESS('全部完成！可以刷新前端页面查看效果'))
        self.stdout.write(self.style.SUCCESS('=' * 60))

